#ifndef _PIPE_H_
#define _PIPE_H_

#include "Typedef.h"
#include "compiler.h"
#include "component_uotghs.h"
#include "UOtgGeneralRegs.h"
#include "UOtgHostRegs.h"

typedef void(*PipeFun)(struct _Pipe* pPipe);

typedef struct _Pipe
{
	uint8	m_isBulkIn:1;	//Is BulkIn Pipe?
	uint8 	m_PipeNum;
	volatile Uotghs* m_pOtgHs;
	
	volatile HostPipeCfgReg* 	m_pPipeCfgReg;
	volatile HostPipeStatusReg* m_pPipeStatusReg;
	volatile HostPipeClsReg* 	m_pPipeClsReg;
	volatile HostPipeSetReg* 	m_pPipeSetReg;
	volatile HostPipeMaskReg* 	m_pPipeMaskReg;
	volatile HostPipeDisReg* 	m_pPipeDisReg;
	volatile HostPipeEnReg* 	m_pPipeEnReg;
	volatile HostPipeInReqReg* 	m_pPipeInReqReg;
	volatile HostPipeErrReg* 	m_pPipeErrReg;

	PipeFun	Isr;
}Pipe;

Bool Pipe_Init(Pipe* pPipe, uint8 addr, uint8 pipeNum, uint16 size);
void Pipe_Start(Pipe* pPipe);

////////////////////////////////////////////////////
typedef struct _SetupReq
{
	uint8 bmRequestType;
	uint8 bRequest;
	uint16 wValue;
	uint16 wIndex;
	uint16 wLength;
}SetupReq;

typedef enum _UsbStatus
{
	URB_STATUS_INIT = 0,	//URB initialize
	URB_STATUS_SUCCESS,		// Request success
	URB_STATUS_FAIL,		// Request fail
	URB_STATUS_CANCEL,		// Request cancel
	URB_STATUS_STALL,		// Request fail
	URB_STATUS_PROCESS		//URB in process
}UsbStatus;


typedef void (*TransDoneFun)(void* pArgs, SetupReq* pSetup, uint16 nPayloadSize, UsbStatus status);

//SETUP usb request block.
typedef struct _SetupUrb
{
	// urb status, the value in URB_STATUS
    uint8 		m_Status;
	
	SetupReq	m_SetupReq;
	
	uint16		m_PayLoadSize;
	uint8*		m_pPayLoad;
	
	// Actual transfer data length, in bytes
	uint16		m_ActTransSize;
	
	TransDoneFun 	TransDone;		//Tx SetupReq Done to callback function,
	void*		m_pArg;		//Arg for calling TransDone func
}SetupUrb;

typedef struct _CtrlPipe
{
	Pipe		m_Base;

	uint8 		m_isPending:1;	//Do has SetupReq to Tx?
	uint8 		m_Phase:3;	
	uint8 		m_Reserved:4;	
	
	uint16		m_TimeOut;

	SetupUrb	m_SetupUrb;	
}CtrlPipe;

bool CtrlPipe_TxSetupReq(CtrlPipe* pCtrlPipe, const SetupReq* pReq, const void* payload, uint16 payloadSize, TransDoneFun TxSetupDone, void* pArg);
void CtrlPipe_isr(CtrlPipe* pCtrlPipe);
void CtrlPipe_Init(CtrlPipe* pCtrlPipe, uint8 addr, uint8 pipeNum);

////////////////////////////////////////////////////
typedef struct _BlkInPipe
{
	Pipe	m_Base;
}BlkInPipe;

void BlkInPipe_Init(BlkInPipe* pBlkInPipe, uint8 addr, uint8 pipeNum, uint16 pktSize);
////////////////////////////////////////////////////
typedef struct _BlkOutPipe
{
	Pipe	m_Base;
}BlkOutPipe;
void BlkOutPipe_Init(BlkOutPipe* pBlkOutPipe, uint8 addr, uint8 pipeNum, uint16 pktSize);

#endif

